package com.supor.aiot.common.helper;

import android.Manifest;
import android.app.Dialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.android.shareassist.constants.ShareExtraInfoConstant;
import com.alipay.mobile.common.share.ShareContent;
import com.alipay.mobile.common.share.constant.ShareType;
import com.alipay.mobile.framework.quinoxless.QuinoxlessFramework;
import com.alipay.mobile.framework.service.ShareService;
import com.android.baseconfig.common.helper.PermissionsChecker;
import com.android.baseconfig.common.utils.DialogUtils;
import com.android.baseconfig.common.utils.FileUtil;
import com.android.baseconfig.common.utils.Logc;
import com.android.baseconfig.common.utils.ThreadUtils;
import com.android.baseconfig.common.utils.ToastUtils;
import com.android.baseconfig.common.views.AppBasicDialog;
import com.android.baseconfig.data.http.okhttp.listener.DownloadProgressListener;
import com.bumptech.glide.Glide;
import com.bytedance.sdk.open.aweme.base.MediaContent;
import com.bytedance.sdk.open.aweme.base.VideoObject;
import com.bytedance.sdk.open.aweme.share.Share;
import com.bytedance.sdk.open.douyin.DouYinOpenApiFactory;
import com.bytedance.sdk.open.douyin.DouYinOpenConfig;
import com.bytedance.sdk.open.douyin.api.DouYinOpenApi;
import com.mpaas.framework.adapter.api.MPFramework;
import com.supor.aiot.common.R;
import com.supor.aiot.common.app.AppAgent;
import com.supor.aiot.common.app.AppInit;
import com.supor.aiot.common.app.Constants;
import com.supor.aiot.common.app.SuporPresenter;
import com.supor.aiot.common.app.api.DownloadImpl;
import com.supor.aiot.common.interfaces.ShareListener;
import com.supor.aiot.common.ui.activity.SuporPermissionActivity;
import com.supor.aiot.common.utils.Base64Utils;
import com.supor.aiot.common.utils.MarketUtils;
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutionException;

import androidx.core.content.FileProvider;

/**
 * ---------------------------------------------------------------- <br>
 * Copyright (C) 2014-2020, by het, Shenzhen, All rights reserved.  <br>
 * ---------------------------------------------------------------- <br>
 * <p>
 * 描述: 社交分享 <br>
 * 作者: lei <br>
 * 日期: 2020/9/12 <br>
 */
public class ShareHelper {
    private Context context;
    private static final String SHARE_BIZ = "suporTiny";
    private ShareService service;
    private ShareListener mShareListener;
    private byte[] mWechatDefaultIconBytes;
    private long startTime;
    private AppBasicDialog commonDialog;

    public ShareHelper(Context context) {
        this.context = context;
        initService();
        initListener();
        initDefaultIcon();
        // 抖音分享初始化
        DouYinOpenApiFactory.init(new DouYinOpenConfig(Constants.App.DouYinClientKey));
    }

    /**
     * 初始化service
     */
    private void initService() {
        if (!QuinoxlessFramework.initSuccess()) {
            AppInit.getInstance().setup(AppAgent.getApp(), null);
            AppInit.getInstance().onCreate();
            return;
        }
        service = MPFramework.getExternalService(ShareService.class.getName());
        service.initWeixin(Constants.App.WeixinAppId, Constants.App.WeixinSecret);
        service.initWeiBo(Constants.App.WeiBoAppId, Constants.App.WeiBoSecret, Constants.App.WeiBoRedirectUrl);
        service.initQQ(Constants.App.QQAppId);
        service.initQZone(Constants.App.QQAppId);
        service.initAlipayContact(Constants.App.AlipayAppId);
        // service.initAlipayContact("2016111102737103");
        // service.initDingDing("dingoa7rxo7sxowhwpg5ke");
        service.setAppName(context.getResources().getString(R.string.app_name));
    }

    /**
     * 初始化分享回调
     */
    private void initListener() {
        mShareListener = new ShareListener(context);
        service.setShareActionListener(mShareListener);
    }

    /**
     * 初始化默认图片
     */
    private void initDefaultIcon() {
        ThreadUtils.execute(() -> {
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.app_share_icon);
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
                mWechatDefaultIconBytes = bos.toByteArray();
                bos.flush();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    public void shareMsg(JSONObject jo) {
        JSONObject jsonObject = (JSONObject) jo.clone();

        // 分享类型：0取消分享；1微信；2微信朋友圈；3 QQ好友；4 QQ空间；5微博；6支付宝；7抖音；8复制链接分享
        int shareType = jo.getIntValue(Constants.Key.param_shareType);
        if (shareType == 1 || shareType == 2) {
            if (!MarketUtils.getTools().isInstalled(context, Constants.App.WeixinPackage)) {
                showDialog(Constants.App.WeixinPackage);
                return;
            }
        } else if (shareType == 7) {
            if (!MarketUtils.getTools().isInstalled(context, Constants.App.DouyinPackage)) {
                showDialog(Constants.App.DouyinPackage);
                return;
            }
            if (checkPermission(jo)) {
                return;
            }

        } else if (shareType == 5) {
            if (!MarketUtils.getTools().isInstalled(context, Constants.App.WeiboPackage)) {
                showDialog(Constants.App.WeiboPackage);
                return;
            }
        }
        if (shareType == 8) {
            String sharUrl = jo.getString(Constants.Key.param_shareUrl);
            if (!TextUtils.isEmpty(sharUrl)) {
                //获取剪贴板管理器：
                ClipboardManager cm = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
// 创建普通字符型ClipData
                ClipData mClipData =  ClipData.newRawUri("shareUrl", Uri.parse(sharUrl));
// 将ClipData内容放到系统剪贴板里。
                cm.setPrimaryClip(mClipData);
                ToastUtils.getInstance().showCustomToast("分享链接已复制~");
            }
            return;
        }

        // 分享方式：0x1-text，0x2-image，0x3-URL
        int type = jo.getIntValue(Constants.Key.param_type);
        // 当type是分享url方式时，0表示H5页面分享（直接分享imageUrl字段的url），
        // 1表示小程序分享(分享的url通过appId(本地代码获取应用id),page(对应path字段)
        int tinyAppShare = jo.getIntValue(Constants.Key.param_tinyAppShare);
        // 分享标题
        String title = jo.getString(Constants.Key.param_title);
        // 分享内容描述
        String desc = jo.getString(Constants.Key.param_desc);
        // URL连接，小程序路径
        String path = jo.getString(Constants.Key.param_path);
        // 自定义分享小图标元素，所有分享优先使用分享图片 URL（imgUrl）
        String imageUrl = jo.getString(Constants.Key.param_imageUrl);
        // 自定义分享预览大图，建议尺寸 750x825
        String bgImgUrl = jo.getString(Constants.Key.param_bgImgUrl);
        String videoUrl = jo.getString(Constants.Key.param_videoUrl);

        if (shareType == 7) { // 抖音分享
            shareToDouYin(videoUrl);
            return;
        }

        final ShareContent content = new ShareContent();
        // 设置分享标题
        content.setTitle(title != null ? title : "supor share title");
        // 设置分享内容
        content.setContent(desc != null ? desc : "supor share content");
        // 设置分享类型，分享链接请选择"url"
        content.setContentType(type == 3 ? "url" : "image");
        // 设置分享图片地址，微信分享请保证图片小于32KB
        if (type == 3) { // url
            Logc.i("share: " + jo.toJSONString());
            if (tinyAppShare == 0) { // url
                if (!TextUtils.isEmpty(path)) {
                    content.setUrl(path);
                } else {
                    content.setUrl("http://www.supor.com");
                }
                if (shareType == 5) { // weibo
                    if (title != null) { // 微博显示的是content
                        content.setContent(title);
                    }
                    // content.setImage(mWechatDefaultIconBytes);
                    // content.setImgUrl(bgImgUrl);
                    // content.setIconUrl(bgImgUrl);
                } else {
                    // 微信缩略图转换成byte数组
                    if (!TextUtils.isEmpty(bgImgUrl)) {
                        byte[] data = urlToIcon(bgImgUrl);
                        if (data != null) {
                            content.setImage(data);
                        } else {
                            content.setImgUrl(bgImgUrl);
                        }
                    } else {
                        content.setImage(mWechatDefaultIconBytes);
                    }
                }
            } else {
                content.setUrl(path);
                content.setImgUrl(bgImgUrl);
            }
        } else { // image
            jsonObject.remove(Constants.Key.param_imageUrl);
            Logc.i("share: " + jsonObject.toJSONString());
            if (shareType == 5) { // weibo
                content.setUrl(" ");
                content.setTitle("分享图片");
                content.setContent("分享图片");
            }
            if (!TextUtils.isEmpty(bgImgUrl)) {
                content.setImgUrl(bgImgUrl);
            } else {
                // base64图片转换
                content.setImage(Base64Utils.decoderBase64(imageUrl));
            }
        }
        switch (shareType) {
            case 1:
                shareToWechat(content);
                break;
            case 2:
                shareToWechatTimeline(content);
                break;
            case 3:
                shareToQQ(content);
                break;
            case 4:
                shareToQZone(content);
                break;
            case 5:
                shareToWeibo(content);
                break;
            case 6:
                shareToAlipay(content);
                break;
            default:
                break;
        }
    }

    /**
     * url图片大导致分享到微信缩略图不能显示，这里转换成bitmap压缩后再分享
     *
     * @param url 图片URL
     * @return byte[]
     */
    private byte[] urlToIcon(String url) {
        byte[] data = null;
        try {
            Bitmap bitmap = Glide.with(context).asBitmap().load(url).submit(100, 200).get();
            Logc.i("urlToIcon: b.w= " + bitmap.getWidth() + ", b.h= " + bitmap.getHeight());
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
            data = bos.toByteArray();
            bos.flush();
            bos.close();
        } catch (ExecutionException | InterruptedException | IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    private boolean checkPermission(JSONObject jo) {
        PermissionsChecker mPermissionsChecker = new PermissionsChecker(context);
        if (mPermissionsChecker.lacksPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            ArrayList<String> list = new ArrayList<>();
            list.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            String[] permissionStr = new String[list.size()];
            list.toArray(permissionStr);
            Intent intent = new Intent(AppAgent.getCurrentActivity(),
                    SuporPermissionActivity.class);
            intent.putStringArrayListExtra(Constants.Key.param_list, list);
            // param填3表示本地分享请求权限
            intent.putExtra(Constants.Key.param_params, 3);
            intent.putExtra(Constants.Key.param_type, 2);
            intent.putExtra(Constants.Key.param_msg, jo);
            AppAgent.getCurrentActivity().startActivity(intent);
            return true;
        }
        return false;
    }

    /**
     * 分享到支付宝
     *
     * @param content 分享内容
     */
    public void shareToAlipay(ShareContent content) {
        service.silentShare(content, ShareType.SHARE_TYPE_ALIPAY, SHARE_BIZ);
    }

    /**
     * 分享到微信好友
     *
     * @param content 分享内容
     */
    public void shareToWechat(ShareContent content) {
        setWechatDefaultIcon(content);
        service.setShareActionListener(mShareListener);
        service.silentShare(content, ShareType.SHARE_TYPE_WEIXIN, SHARE_BIZ);
    }

    /**
     * 分享到微信朋友圈
     *
     * @param content 分享内容
     */
    public void shareToWechatTimeline(ShareContent content) {
        setWechatDefaultIcon(content);
        service.silentShare(content, ShareType.SHARE_TYPE_WEIXIN_TIMELINE, SHARE_BIZ);
    }

    /**
     * 分享到微博
     *
     * @param content 分享内容
     */
    public void shareToWeibo(ShareContent content) {
        service.silentShare(content, ShareType.SHARE_TYPE_WEIBO, SHARE_BIZ);
    }

    /**
     * 分享到QQ
     *
     * @param content 分享内容
     */
    public void shareToQQ(ShareContent content) {
        service.silentShare(content, ShareType.SHARE_TYPE_QQ, SHARE_BIZ);
    }

    /**
     * 分享到QZone
     *
     * @param content 分享内容
     */
    public void shareToQZone(ShareContent content) {
        service.silentShare(content, ShareType.SHARE_TYPE_QZONE, SHARE_BIZ);
    }

    Dialog dialog;

    /**
     * 分享到抖音，需要先下载视频
     *
     * @param url 分享内容url
     */
    public void shareToDouYin(String url) {
        if (TextUtils.isEmpty(url)) {
            ToastUtils.getInstance().showCustomToast(context, "douyin share url can't be null");
            return;
        }
        String fileName = url.substring(url.lastIndexOf("/") + 1);
        String filePath =
                FileUtil.getExternalStoragePath() + "/Download/苏泊尔/" + fileName;
        FileUtil.createDirs(FileUtil.getExternalStoragePath() + "/Download/苏泊尔");
        // 该filePath对应于xml/file_provider_paths里的第一行配置：，因此才可被共享
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        try {
            boolean b = file.createNewFile();
            Logc.i("getDouYinFileUri: createNewFile: " + b);
            if (!b) {
                Logc.e("shareToDouYin: douyin share createNewFile failed");
                return;
            }
        } catch (IOException e) {
            e.printStackTrace();
            Logc.e("shareToDouYin: douyin share failed: " + e.getMessage());
            return;
        }

        DownloadImpl.getInstance().download(url, filePath, new DownloadProgressListener() {
            @Override
            public void onStart() {
                Logc.i("onStart: ");
                startTime = System.currentTimeMillis();
                AppAgent.getCurrentActivity().runOnUiThread(() -> {
                    dialog = DialogUtils.createLoadingDialog(AppAgent.getCurrentActivity(),
                            "视频下载中");
                    dialog.setCancelable(false);
                    dialog.show();
                });

            }

            @Override
            public void update(long bytesRead, long contentLength, boolean done) {
                reportDownloadStatus(done ? 1 : 0, bytesRead, contentLength, "");
            }

            @Override
            public void onFailed(Throwable throwable) {
                Logc.i("onFailed: " + throwable);
                ToastUtils.getInstance().showCustomToast("视频下载失败，请尝试重新分享");
                reportDownloadStatus(2, 0, 0, throwable.getMessage());
            }

            @Override
            public void onComplete(String path) {
                Logc.i("onComplete: " + path);
                Logc.i("onComplete: time= " + (System.currentTimeMillis() - startTime) / 1000.0);
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                }
                reportDownloadStatus(1, 0, 0, path);
                shareToDouYin(file);
            }
        });
    }

    private void reportDownloadStatus(int state, long bytesRead, long contentLength, String msg) {
        ThreadUtils.execute(() -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(Constants.Key.param_state, state);
            jsonObject.put(Constants.Key.param_progress, bytesRead);
            jsonObject.put(Constants.Key.param_total, contentLength);
            jsonObject.put(Constants.Key.param_msg, msg);
            SuporPresenter.getInstance().reportDownloadStatus(jsonObject.toJSONString());
        });
    }

    private void shareToDouYin(File file) {
        String fileUrl = getDouYinFileUri(context, file);
        Logc.i("shareToDouYin: fileUrl: " + fileUrl);
        DouYinOpenApi douyinOpenApi = DouYinOpenApiFactory.create(AppAgent.getCurrentActivity());
        ArrayList<String> videos = new ArrayList<>();
        videos.add(fileUrl);
        if (douyinOpenApi.isShareSupportFileProvider() &&
                android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            Share.Request request = new Share.Request();
            VideoObject videoObject = new VideoObject();
            videoObject.mVideoPaths = videos; // 该地方路径可以传FileProvider格式的路径
            MediaContent content = new MediaContent();
            content.mMediaObject = videoObject;
            request.mMediaContent = content;
            douyinOpenApi.share(request);
        } else {
            ToastUtils.getInstance().showToast(context, "版本不符合：安卓系统版本需要大于7.0");
        }
    }

    public String getDouYinFileUri(Context context, File file) {
        // String contentPath = getFileUri(context, file);
        // 使用contentPath作为文件路径进行分享
        // 要与`AndroidManifest.xml`里配置的`authorities`一致，假设你的应用包名为com.example.app
        Uri contentUri = FileProvider.getUriForFile(context,
                "com.supor.aiot.fileprovider", file);
        // 授权给抖音访问路径,这里填抖音包名
        context.grantUriPermission("com.ss.android.ugc.aweme",
                contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
        return contentUri.toString();   // contentUri.toString() 即是以"content://"开头的用于共享的路径
    }

    private void setWechatDefaultIcon(ShareContent content) {
        HashMap<String, Object> extraInfo = content.getExtraInfo();
        if (null == extraInfo) {
            extraInfo = new HashMap<>();
        }
        if (null == extraInfo.get(ShareExtraInfoConstant.DEFAULT_ICON)
                || !(extraInfo.get(ShareExtraInfoConstant.DEFAULT_ICON) instanceof byte[])) {
            extraInfo.put(ShareExtraInfoConstant.DEFAULT_ICON, mWechatDefaultIconBytes);
        }
        content.setExtraInfo(extraInfo);
    }

    /**
     * 跳转微信会员中心小程序
     */
    public void startWXTiny(int type) {
        if (!MarketUtils.getTools().isInstalled(context, Constants.App.WeixinPackage)) {
            // ToastUtils.getInstance().showCustomToast("您未安装微信App");
            SuporPresenter.getInstance().reportShareStatus(40501);
            return;
        }
        if (type == 0) {
            String appId = "wx29135df42114f4ef"; // 填应用AppId
            IWXAPI api = WXAPIFactory.createWXAPI(context, Constants.App.WeixinAppId);

            WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
            // 填小程序原始id
            req.userName = "gh_c5c354846c7e";
            // 拉起小程序页面的可带参路径，不填默认拉起小程序首页，
            // 对于小游戏，可以只传入 query 部分，来实现传参效果，如：传入 "?foo=bar"。
            req.path = "/pages/home/home.html";
            // 可选打开 开发版，体验版和正式版
            req.miniprogramType = WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE;
            api.sendReq(req);
        } else if (type == 1) {
            String appId = "wx29135df42114f4ef"; // 填应用AppId
            IWXAPI api = WXAPIFactory.createWXAPI(context, Constants.App.WeixinAppId);

            WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
            // 填小程序原始id
            req.userName = "gh_c5c354846c7e";
            // 拉起小程序页面的可带参路径，不填默认拉起小程序首页，
            // 对于小游戏，可以只传入 query 部分，来实现传参效果，如：传入 "?foo=bar"。
            req.path = "/pages/home/home.html";
            // 可选打开 开发版，体验版和正式版
            req.miniprogramType = WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE;
            api.sendReq(req);
        }
    }

    public void showDialog(String packgeName) {
        AppAgent.getCurrentActivity().runOnUiThread(() -> {
            if (commonDialog != null && commonDialog.isShowing()) {
                commonDialog.dismiss();
            }
            AppBasicDialog.Builder builder = new AppBasicDialog.Builder(AppAgent.getCurrentActivity(), false);
            builder.setTitle(context.getResources().getString(R.string.share_dialog_title));
            builder.setMessage(context.getResources().getString(R.string.share_dialog_msg));
            builder.setNegativeColor(context.getResources().getColor(R.color.content_default50));
            builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
            builder.setPositiveButton(R.string.go_download, new DownloadAPPCallback(packgeName));
            commonDialog = builder.create();
            commonDialog.setCancelable(false);
            commonDialog.show();
        });
    }

    public void destroy() {
    }

    class DownloadAPPCallback implements DialogInterface.OnClickListener {

        private String packageName;

        public DownloadAPPCallback(String packageName) {
            this.packageName = packageName;
        }

        @Override
        public void onClick(DialogInterface dialog, int which) {
            MarketUtils.getTools().startMarket(context, packageName);
            dialog.dismiss();
        }
    }
}
